
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Token {
	
	private JFrame frmtoken;
	private JTextField textField;
	private JTextField textField_1;
	private JTextField textField_2;
	
	
	public static String assembleToken(String version, String resourceName, String expirationTime,
			String signatureMethod, String accessKey)
			throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
		StringBuilder sb = new StringBuilder();
		String res = URLEncoder.encode(resourceName, "UTF-8");
		String sig = URLEncoder
				.encode(generatorSignature(version, resourceName, expirationTime, accessKey, signatureMethod), "UTF-8");
		sb.append("version=").append(version).append("&res=").append(res).append("&et=").append(expirationTime)
				.append("&method=").append(signatureMethod).append("&sign=").append(sig);
		return sb.toString();
	}

	public static String generatorSignature(String version, String resourceName, String expirationTime,
			String accessKey, String signatureMethod) throws NoSuchAlgorithmException, InvalidKeyException {
		String encryptText = expirationTime + "\n" + signatureMethod + "\n" + resourceName + "\n" + version;
		String signature;
		byte[] bytes = HmacEncrypt(encryptText, accessKey, signatureMethod);
		signature = Base64.getEncoder().encodeToString(bytes);
		return signature;
	}

	public static byte[] HmacEncrypt(String data, String key, String signatureMethod)
			throws NoSuchAlgorithmException, InvalidKeyException {
		// 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
		SecretKeySpec signinKey = null;
		signinKey = new SecretKeySpec(Base64.getDecoder().decode(key), "Hmac" + signatureMethod.toUpperCase());

		// 生成一个指定 Mac 算法 的 Mac 对象
		Mac mac = null;
		mac = Mac.getInstance("Hmac" + signatureMethod.toUpperCase());

		// 用给定密钥初始化 Mac 对象
		mac.init(signinKey);

		// 完成 Mac 操作
		return mac.doFinal(data.getBytes());
	}

	public enum SignatureMethod {
		SHA1, MD5, SHA256;
	}
	
	private  void initialize() {
		frmtoken = new JFrame();
		frmtoken.setTitle("中移和物Token");
		frmtoken.setBounds(100, 100, 438, 294);
		frmtoken.setLocationRelativeTo(null);
		frmtoken.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmtoken.getContentPane().setLayout(new BorderLayout(0, 0));
		
		JPanel panel = new JPanel();
		frmtoken.getContentPane().add(panel, BorderLayout.CENTER);
		panel.setLayout(null);
		
		JLabel lblNewLabel = new JLabel("产品id:");
		lblNewLabel.setBounds(85, 11, 54, 27);
		panel.add(lblNewLabel);
		
		textField = new JTextField();
		textField.setBounds(149, 10, 187, 30);
		panel.add(textField);
		textField.setColumns(10);
		
		JLabel lblid = new JLabel("设备id:");
		lblid.setBounds(85, 52, 54, 27);
		panel.add(lblid);
		
		textField_1 = new JTextField();
		textField_1.setColumns(10);
		textField_1.setBounds(149, 51, 187, 30);
		panel.add(textField_1);
		
		JLabel lblKey = new JLabel("KEY:");
		lblKey.setBounds(85, 93, 54, 27);
		panel.add(lblKey);
		
		textField_2 = new JTextField();
		textField_2.setColumns(10);
		textField_2.setBounds(149, 92, 187, 30);
		panel.add(textField_2);
		
		JTextArea textArea = new JTextArea();
		textArea.setRows(10);
		textArea.setLineWrap(true);
		textArea.setBounds(43, 166, 355, 80);
		panel.add(textArea);
		
		JButton btnNewButton = new JButton("生成");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String productId=textField.getText();
				String deviceId=textField_1.getText();
				String accessKey=textField_2.getText();
				
				String resourceName = "products/"+productId;
				if(deviceId!=null&&!"".equals(deviceId)) {
					resourceName+="/devices"+deviceId;
				}
				String version = "2018-10-31";
				// 设置有效期为1000天
				String expirationTime = System.currentTimeMillis() / 1000 + 1000 * 24 * 60 * 60 + "";
				String signatureMethod = SignatureMethod.SHA1.name().toLowerCase();
				try {
					String token = assembleToken(version, resourceName, expirationTime, signatureMethod, accessKey);
					textArea.setText(token);
				} catch (Exception e1) {
					e1.printStackTrace();
				}
				
				
				
			}
		});
		btnNewButton.setBounds(159, 132, 93, 23);
		panel.add(btnNewButton);
	}
	
	public Token() {
		initialize();
	}

	public static void main(String[] args) throws Exception {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Token window = new Token();
					window.frmtoken.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	public static void testToken()  throws Exception {
		// 访问资源 resource
		// 产品级格式为：products/{产品id}
		// 设备级格式为：products/{产品id}/devices/{设备名字}
		// String resourceName = "products/5VN8GjnK28/devices/test";
		// String accessKey = "YUk4ajdOR3h2RVhCcjBYUHhnZnRsbzVtcUttYXZTa2w=";
		// 下面使用产品级别密钥
		String resourceName = "products/mSs4Q50dAx";
		String accessKey = "573NOXWxZxHrDf91t6NBQ1EDt5/BgQsJn3FxQc3NS+8=";
		
		String version = "2018-10-31";
		// 设置有效期为1000天
		String expirationTime = System.currentTimeMillis() / 1000 + 1000 * 24 * 60 * 60 + "";
		String signatureMethod = SignatureMethod.SHA1.name().toLowerCase();
		String token = assembleToken(version, resourceName, expirationTime, signatureMethod, accessKey);
		System.out.println("Authorization:\r\n" + token);
		
	}
}
